#ifndef USB_TYPEDEF_H
#define USB_TYPEDEF_H

#include "attribute_typedef.h"
#include "remote_control.h"
#include "struct_typedef.h"

#define DEBUG_PACKAGE_NUM 10

#define DATA_DOMAIN_OFFSET 0x08

#define SEND_SOF    ((uint8_t)0x99)
#define RECEIVE_SOF ((uint32_t)0x23)

#define ROBOT_INFO_DATA_SEND_ID   ((uint8_t)0x5D)
#define ALL_ROBOT_HP_SEND_ID      ((uint8_t)0x5B)
#define GAME_STATUS_SEND_ID       ((uint8_t)0x5C)
#define VISION_SEND_ID            ((uint8_t)0x5A)

#define ROBOT_CMD_DATA_RECEIVE_ID  ((uint8_t)0xA3)
#define VISION_RECEIVE_ID          ((uint8_t)0xA5)
#define SIMULATION_RECEIVE_ID      ((uint8_t)0xA4)

/*-------------------- Header --------------------*/

typedef struct
{
    uint8_t sof;  // 数据帧起始字节，固定值为 0x5A
    uint8_t len;  // 数据段长度
    uint8_t id;   // 数据段id
    uint8_t crc;  // 数据帧头的 CRC8 校验
} __packed__ FrameHeader_t;


/*-------------------- Send --------------------*/

// 机器人信息数据包
typedef struct
{
    uint8_t id;             // 数据段id = 0x5D
    struct
    {
        uint8_t robot_id;
        uint16_t current_hp;
        uint16_t shooter_heat;
        bool team_color;
        bool is_attacked;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataRobotInfo_s;


// 全场机器人hp信息数据包
typedef struct
{
    uint8_t id;             // 数据段id = 0x5B
    struct
    {
        uint16_t red_1_robot_hp;
        uint16_t red_2_robot_hp;
        uint16_t red_3_robot_hp;
        uint16_t red_4_robot_hp;
        uint16_t red_5_robot_hp;
        uint16_t red_7_robot_hp;
        uint16_t red_outpost_hp;
        uint16_t red_base_hp;
        uint16_t blue_1_robot_hp;
        uint16_t blue_2_robot_hp;
        uint16_t blue_3_robot_hp;
        uint16_t blue_4_robot_hp;
        uint16_t blue_5_robot_hp;
        uint16_t blue_7_robot_hp;
        uint16_t blue_outpost_hp;
        uint16_t blue_base_hp;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataAllRobotHp_s;

// 比赛信息数据包
typedef struct
{
    uint8_t id;             // 数据段id = 0x5C
    struct
    {
        uint8_t game_progress;
        uint16_t stage_remain_time;
        bool is_center_buff_down; // 0 没人 1有人
        uint8_t center_buff_down;//0 没人  1 友方 2 对方 3 双方占领 4 自己踩到
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataGameStatus_s;

// 视觉发送数据包
typedef struct
{
    uint8_t id;                // 数据段id = 0x5A
    uint32_t time_stamp;
    struct
    {
        uint8_t detect_color : 1;      // 0-red 1-blue 2-unknown
        bool reset_tracker: 1;  // 0-不重新跟踪 1-重新跟踪
        uint8_t reserved : 6;
                
        float roll;   // rad
        float pitch;  // rad
        float yaw;    // rad
        float aim_x;
        float aim_y;
        float aim_z;
    } __packed__ data;
    uint16_t crc;
} __packed__ SendDataVision_s;

/*-------------------- Receive --------------------*/
typedef struct RobotCmdData
{
    FrameHeader_t frame_header;  // 数据段id = 0x01
    uint32_t time_stamp;
    struct
    {
        bool stop_gimbal_scan;  // 云台是否扫描 1-不扫描 0-扫描
        float chassis_spin_vel; //底盘小陀螺速度， 单位rad/s 0-1
        float chassis_speed_k;  //底盘平移速度系数          0-1
    } __packed__ data;
    uint16_t checksum;
} __packed__ ReceiveDataRobotCmd_s;

// 视觉接收数据包
typedef struct
{
    FrameHeader_t frame_header; // 数据段id = 0x04
    uint32_t time_stamp;
    struct
    {
        bool tracking;          // 代表当前是否锁定目标
        uint8_t robot_id : 3;         // 0-outpost 6-guard 7-base
        uint8_t armors_num : 3; // 2-balance 3-outpost 4-normal
        uint8_t reserved : 1;

        float x;                // 目标在世界坐标系下的 x 坐标
        float y;                // 目标在世界坐标系下的 Y 坐标
        float z;                // 目标在世界坐标系下的 Z 坐标

        float yaw;              // 目标在世界坐标系下的倾斜角度
        float v_yaw;            // 目标旋转的角速度
        
        float vx;               // 目标在世界坐标系下 x 方向的速度
        float vy;               // 目标在世界坐标系下 y 方向的速度
        float vz;               // 目标在世界坐标系下 z 方向的速度
        
        float r1;               // 目标其中一组装甲板相对中心的半径
        float r2;               // 目标另一组装甲板相对中心的半径

        float dz; // tracking 中的装甲板的上一块装甲板的 z 轴位置
    } __packed__ data;
    uint16_t crc;
} __packed__ ReceiveDataVision_s;

// 导航控制数据包
typedef struct
{
    FrameHeader_t frame_header;  // 数据段id = 0x03
    uint32_t time_stamp;
    struct
    {
        float linear_x;
        float linear_y;
        float linear_z;
        float angular_x;
        float angular_y;
        float angular_z;
    } __packed__ data;
    uint16_t crc;
} __packed__ ReceiveDataSimulation_s;

#endif  
